package org.concept.chinachesspieces.core;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

/**
 *@author xww 判断将军
 */
public class Check {
	public static Logger log = LogManager.getLogger(Check.class);

	/**
	 * 马是否将住对方老将
	 * 
	 * @param bs
	 *            棋盘
	 * @param i
	 *            马的横向坐标
	 * @param j
	 *            马的纵向坐标
	 * @param marshal
	 *            对方老将的坐标
	 * @return 马是否将住对方老将
	 */
	private static boolean checkByHorse(byte[][] bs, int i, int j, byte marshal) {
		if (i > 1 && j > 0 && bs[i - 1][j] == Constants.EMPTY
				&& bs[i - 2][j - 1] == marshal)
			return true;
		if (i > 1 && j < 8 && bs[i - 1][j] == Constants.EMPTY
				&& bs[i - 2][j + 1] == marshal)
			return true;
		if (i > 0 && j > 1 && bs[i][j - 1] == Constants.EMPTY
				&& bs[i - 1][j - 2] == marshal)
			return true;
		if (i < 9 && j > 1 && bs[i][j - 1] == Constants.EMPTY
				&& bs[i + 1][j - 2] == marshal)
			return true;
		if (i > 0 && j < 7 && bs[i][j + 1] == Constants.EMPTY
				&& bs[i - 1][j + 2] == marshal)
			return true;
		if (i < 9 && j < 7 && bs[i][j + 1] == Constants.EMPTY
				&& bs[i + 1][j + 2] == marshal)
			return true;
		if (i < 8 && j > 0 && bs[i + 1][j] == Constants.EMPTY
				&& bs[i + 2][j - 1] == marshal)
			return true;
		if (i < 8 && j < 8 && bs[i + 1][j] == Constants.EMPTY
				&& bs[i + 2][j + 1] == marshal)
			return true;
		return false;
	}

	/**
	 * 判断红兵是否将住黑方老将
	 * 
	 * @param bs
	 *            棋盘
	 * @param i
	 *            红兵的横向坐标
	 * @param j
	 *            红兵的纵向坐标
	 * @return 红兵是否将住黑方老将
	 */
	private static boolean checkBlackBySoldier(byte[][] bs, int i, int j) {
		if (i < 9 && bs[i + 1][j] == Constants.BLACK_MARSHAL)
			return true;
		if (j > 3  && bs[i][j - 1] == Constants.BLACK_MARSHAL)
			return true;
		if (j < 5 && bs[i][j + 1] == Constants.BLACK_MARSHAL)
			return true;
		return false;
	}

	/**
	 * 判断黑兵是否将住红将
	 * 
	 * @param bs
	 *            棋盘
	 * @param i
	 *            黑兵的横向坐标
	 * @param j
	 *            黑兵的纵向坐标
	 * @return 黑兵是否将住红将
	 */
	private static boolean checkRedBySoldier(byte[][] bs, int i, int j) {
		if (i > 0 && bs[i - 1][j] == Constants.RED_MARSHAL)
			return true;
		if (j > 3 && bs[i][j - 1] == Constants.RED_MARSHAL)
			return true;
		if (j < 5 && bs[i][j + 1] == Constants.RED_MARSHAL)
			return true;
		return false;
	}

	/**
	 * 判断炮是否将住对方老将
	 * 
	 * @param bs
	 *            棋盘
	 * @param i
	 *            炮的横向坐标
	 * @param j
	 *            炮的纵向坐标
	 * @param marshal
	 *            对方老将的坐标
	 * @return 炮是否将住对方老将
	 */
	private static boolean checkByGun(byte[][] bs, int i, int j, byte marshal) {
		int flag = 0;
		for (int x = i - 1; x >= 0; x--) {
			if (bs[x][j] != Constants.EMPTY) {
				flag++;
				if (flag == 2 && bs[x][j] == marshal) {
					return true;
				}
				if (flag >= 2) {
					break;
				}
			}
		}
		flag = 0;
		for (int x = i + 1; x <= 9; x++) {
			if (bs[x][j] != Constants.EMPTY) {
				flag++;
				if (flag == 2 && bs[x][j] == marshal) {
					return true;
				}
				if (flag >= 2) {
					break;
				}
			}
		}
		flag = 0;
		for (int y = j - 1; y >= 0; y--) {
			if (bs[i][y] != Constants.EMPTY) {
				flag++;
				if (flag == 2 && bs[i][y] == marshal) {
					return true;
				}
				if (flag >= 2) {
					break;
				}
			}
		}
		flag = 0;
		for (int y = j + 1; y <= 8; y++) {
			if (bs[i][y] != Constants.EMPTY) {
				flag++;
				if (flag == 2 && bs[i][y] == marshal) {
					return true;
				}
				if (flag >= 2) {
					break;
				}
			}
		}
		return false;
	}

	/**
	 * 判断車是否将住对方老将
	 * 
	 * @param bs
	 *            棋盘
	 * @param i
	 *            车的横向坐标
	 * @param j
	 *            车的纵向坐标
	 * @param marshal
	 *            对方老将的坐标
	 * @return 車是否将住对方老将
	 */
	private static boolean checkByCar(byte[][] bs, int i, int j, byte marshal) {
		for (int x = i - 1; x >= 0; x--) {
			if (bs[x][j] == Constants.EMPTY) {
				continue;
			} else if (bs[x][j] == marshal) {
				return true;
			} else {
				break;
			}
		}
		for (int x = i + 1; x <= 9; x++) {
			if (bs[x][j] == Constants.EMPTY) {
				continue;
			} else if (bs[x][j] == marshal) {
				return true;
			} else {
				break;
			}
		}
		for (int y = j - 1; y >= 0; y--) {
			if (bs[i][y] == Constants.EMPTY) {
				continue;
			} else if (bs[i][y] == marshal) {
				return true;
			} else {
				break;
			}
		}
		for (int y = j + 1; y <= 8; y++) {
			if (bs[i][y] == Constants.EMPTY) {
				continue;
			} else if (bs[i][y] == marshal) {
				return true;
			} else {
				break;
			}
		}
		return false;
	}

	/**
	 * 判读黑方是否被红方将军
	 * 
	 * @param bs
	 *            棋盘
	 * @return 黑方是否被将军
	 */
	public static boolean checkBlack(byte[][] bs) {
		for (int i = 0; i < bs.length; i++) {
			for (int j = 0; j < bs[i].length; j++) {
				byte curr = bs[i][j];
				switch (curr) {
				case Constants.RED_CAR:
					if (checkByCar(bs, i, j, Constants.BLACK_MARSHAL)) {
						return true;
					}
					break;
				case Constants.RED_HORSE:
					if (checkByHorse(bs, i, j, Constants.BLACK_MARSHAL)) {
						return true;
					}
					break;
				case Constants.RED_GUN:
					if (checkByGun(bs, i, j, Constants.BLACK_MARSHAL)) {
						return true;
					}
					break;
				case Constants.RED_SOLDIER:
					if (checkBlackBySoldier(bs, i, j)) {
						return true;
					}
					break;
				}
			}
		}
		return false;
	}

	/**
	 * 判断红方是否被黑方将军
	 * 
	 * @param bs
	 *            棋盘
	 * @return 红方是否被将军
	 */
	public static boolean checkRed(byte[][] bs) {
		for (int i = 0; i < bs.length; i++) {
			for (int j = 0; j < bs[i].length; j++) {
				byte curr = bs[i][j];
				switch (curr) {
				case Constants.BLACK_CAR:
					if (checkByCar(bs, i, j, Constants.RED_MARSHAL)) {
						return true;
					}
					break;
				case Constants.BLACK_HORSE:
					if (checkByHorse(bs, i, j, Constants.RED_MARSHAL)) {
						return true;
					}
					break;
				case Constants.BLACK_GUN:
					if (checkByGun(bs, i, j, Constants.RED_MARSHAL)) {
						return true;
					}
					break;
				case Constants.BLACK_SOLDIER:
					if (checkRedBySoldier(bs, i, j)) {
						return true;
					}
					break;
				}
			}
		}
		return false;
	}
}
